﻿using System;
using System.Collections.Generic;
using System.IO;
using QuantBox.XApi;
using Skyline;
using SmartQuant;
using SmartQuant.Quant;
using Random = System.Random;

namespace QuantBox
{
    public class QuantBoxUfx : XProvider, IInstrumentProvider
    {
#if !INC_API
        static QuantBoxUfx()
        {
            AssemblyResolver.AddPath(Path.Combine(Path.GetDirectoryName(Installation.ConfigDir.FullName)!, "XAPI\\x64\\UFX\\"));
        }
#endif
        private const string ProviderName = "QuantBoxUfx";
        private readonly Random _rand = new Random();

        protected override XProviderSettings LoadSettings()
        {
            var defaultSettings = new XProviderSettings {
                Id = QuantBoxConst.PIdUfx,
                Name = ProviderName,
                Url = "www.qauntbox.cn",
                Description = "QuantBox Ufx 插件",
                UserProductInfo = "OpenQuant",
                Connections = new List<ConnectionInfo>(),
                Users = new List<UserInfo>(),
                Servers = new List<ServerInfo>(),
            };
            var settings = XProviderSettings.Load(QBHelper.GetConfigPath(GetSettingsFileName()));
            if (settings == null) {
                settings = defaultSettings;
            }
            else {
                settings.Name = ProviderName;
                settings.Id = defaultSettings.Id;
                settings.Url = defaultSettings.Url;
                settings.Description = defaultSettings.Description;
                foreach (var info in settings.Servers) {
                    if (string.IsNullOrEmpty(info.AuthCode)) {
                        info.AuthCode = GetDiskId();
                    }
                }
            }
            return settings;
        }

        private static string GetDiskId()
        {
            try {
                var (output, _) = new ExternalCall("diskinfoex.exe").WinExecWithPipe();
                return output.Replace("\r",string.Empty).Replace("\n",string.Empty);
            }
            catch {
                // ignored
            }

            return string.Empty;
        }

        protected override ServerInfoField GetServerInfo(ServerInfo server)
        {
            var field = new ServerInfoField();
            field.ConfigPath = QBHelper.MakeAbsolutePath(server.ConfigPath, Installation.ConfigDir.FullName);
            field.ExtInfoChar128 = server.AuthCode;
            return field;
        }

        protected override UserInfoField GetUserInfo(UserInfo user)
        {
            var field = new UserInfoField();
            field.UserID = user.UserId;
            field.Password = user.Password;
            return field;
        }

#if INC_API
        protected override XTradingApi CreateXApi(ConnectionInfo info)
        {
            if ((info.Type & ApiType.Trade) == ApiType.Trade) {
                return new XTradingApi(new UfxTrader());
            }
            return base.CreateXApi(info);
        }
#endif
        protected override IDictionary<string, string> GetServerPropertyMap()
        {
            return new Dictionary<string, string>{
                { "Label", "标识"},
                { "Name", "名称"},
                { "ConfigPath", "t2sdk.ini"},
                { "AuthCode", "硬盘序列号"}
            };
        }

        protected override IDictionary<string, string> GetUserPropertyMap()
        {
            return new Dictionary<string, string>{
                { "Label", "标识"},
                { "UserId", "操作员"},
                { "Password", "密码"}
            };
        }

        protected override void OnConnect()
        {
            ConnectMarketData = false;
            base.OnConnect();
        }

        //protected override string GetLocalId()
        //{
        //    var id = 0;
        //    for (var i = 0; i < LocalIdLength; i++)
        //    {
        //        id += _rand.Next(0, 10) * (int)Math.Pow(10, i);
        //    }

        //    return id.ToString($"D{LocalIdLength}");
        //}

        public QuantBoxUfx(Framework framework)
            : base(framework)
        {
        }
    }
}